package ar.edu.unrn.lia.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;

import org.primefaces.event.SelectEvent;
import org.primefaces.event.map.MarkerDragEvent;
import org.primefaces.event.map.OverlaySelectEvent;
import org.primefaces.event.map.PointSelectEvent;
import org.primefaces.model.map.DefaultMapModel;
import org.primefaces.model.map.LatLng;
import org.primefaces.model.map.MapModel;
import org.primefaces.model.map.Marker;

import ar.edu.unrn.lia.bean.datamodel.LazyBarrioDataModel;
import ar.edu.unrn.lia.model.Barrio;
import ar.edu.unrn.lia.model.Coordenada;
import ar.edu.unrn.lia.model.PuntoInteres;
import ar.edu.unrn.lia.service.BarrioService;

@ManagedBean(name = "barrioBean")
@ViewScoped
public class BarrioBean extends GenericBean<Barrio> implements Serializable {

	private static final long serialVersionUID = 1L;

	@ManagedProperty(value = "#{barrioService}")
	BarrioService entityService;
	
	
	//Maps
	private Coordenada coordenadas = UtilsBean.LATLONG;
	
	private MapModel mapaModel = new DefaultMapModel();
	
	private PuntoInteres puntoInteres = new PuntoInteres();
	
	private Marker marker;
	//Maps
	

	
	public PuntoInteres getPuntoInteres() {
		return puntoInteres;
	}

	public Marker getMarker() {
		return marker;
	}

	public void setMarker(Marker marker) {
		this.marker = marker;
	}

	public void setPuntoInteres(PuntoInteres puntoInteres) {
		this.puntoInteres = puntoInteres;
	}

	public Coordenada getCoordenadas() {
		return coordenadas;
	}

	public void setCoordenadas(Coordenada coordenadas) {
		this.coordenadas = coordenadas;
	}

	public MapModel getMapaModel() {
		return mapaModel;
	}

	public void setMapaModel(MapModel mapaModel) {
		this.mapaModel = mapaModel;
	}

	public String create() {
		setEntity(new Barrio());
		return REDIRECT_CREATE;
	}

	public void onRowSelect(SelectEvent event) {
		agregarMensaje(FacesMessage.SEVERITY_INFO, "Barrio Seleccionado: ",
				((Barrio) event.getObject()).getDescripcion());			
	}

	public String update() {
		try {
						
			if (getEntity().getId() == null) {
				entityService.save(getEntity());
				mensajeFlash("Crear Barrio","Operación realizada con exito.");
			} else {
				entityService.update(getEntity());
				mensajeFlash("Modificar Barrio","Operación realizada con exito.");
			}

			return REDIRECT_SEARCH;
		} catch (OptimisticLockException e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR, "Bloqueo",
					"Alquien modificó este Barrio, reconsulte.");
			return null;
		} catch (Exception e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR, "Error", e.getMessage());
			return null;
		}
	}


	public String delete(Barrio entity) {
		try {
			entityService.delete(entity);
			mensajeFlash("Eliminar Barrio","Operación realizada con exito.");
			return REDIRECT_SEARCH;
		} catch (OptimisticLockException e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR, "Bloqueo",
					"Alquien modificó este Barrio, reconsulte.");
			return null;
		} catch (PersistenceException e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR, "Eliminar Barrio",
					"No se puede eliminar. El Barrio esta asociada a una propiedad.");
			return null;
		} catch (Exception e) {
			agregarMensaje(FacesMessage.SEVERITY_ERROR, "Eliminar Barrio",
					e.getMessage());
			return null;
		}
	}	
	

	@PostConstruct
	public void init()
	{
		setModelLazy(new LazyBarrioDataModel(entityService));
	}
	
	public void inicio() {
		if (!FacesContext.getCurrentInstance().isPostback()) {
			if (getId() != null) {
				setEntity(entityService.getEntityById(getId()));	
				
				loadMap();				
				
			} else {
				setEntity(new Barrio());
			}
		}
	}

	public BarrioService getEntityService() {
		return entityService;
	}

	public void setEntityService(BarrioService entityService) {
		this.entityService = entityService;
	}
	
	public void agregarPuntoInteres()
	{
		getEntity().agregarPuntoInteres(getPuntoInteres());
		setPuntoInteres(new PuntoInteres());		
		loadMap();
	}
	
	public void eliminarPuntoInteres(PuntoInteres pi)
	{
		getEntity().eliminarPuntoInteres(pi);
	}
	
	
	//MAPS
	public void onPointSelect(PointSelectEvent event) {
		agregarMensaje(FacesMessage.SEVERITY_INFO,
				"Se agregaron las siguientes Coordenadas:", "Lat:"
						+ event.getLatLng().getLat() + ", Lon:"
						+ event.getLatLng().getLng());

	}
	
	public void addMarker(ActionEvent actionEvent) {  
        Marker marker = new Marker(new LatLng(getCoordenadas().getLat(), getCoordenadas().getLng()), "");  
        getMapaModel().addOverlay(marker);  
        getPuntoInteres().setDireccion("asdad");
        getPuntoInteres().setNumero(22);      
            
    }  
	
	public void onRowSelectPuntos(SelectEvent event) {
		agregarMensaje(FacesMessage.SEVERITY_INFO, "Barrio Seleccionado: ",
				((PuntoInteres) event.getObject()).getDescripcion());			
	}
	
	
	public void onMarkerSelect(OverlaySelectEvent event) {
		setMarker((Marker) event.getOverlay());
	}
	
	public void eliminarPunto()
	{
		PuntoInteres piEliminar = null;
	      for (PuntoInteres pi : getEntity().getPuntosInteres()) {
	        	if (pi.getId().toString().equals(getMarker().getData()))
	        	{	        		
	        		piEliminar = pi;
	        	}
			}
	      
	      	getEntity().eliminarPuntoInteres(piEliminar);
	      	
	      	loadMap();
	            	
	      	
	}
	
	public void loadMap()
	{
		setMapaModel(new DefaultMapModel());
      	for (PuntoInteres p : getEntity().getPuntosInteres()) {
			getMapaModel().addOverlay(new Marker(new LatLng(p
					.getCoordenada().getLat(), p.getCoordenada().getLng()),
					p.getTipo().toString() + ": " +  p.getDescripcion(), (p.getId()==null?"":p.getId().toString()), FacesContext.getCurrentInstance()
					.getExternalContext().getRequestContextPath()
					+ "/resources/images/"+ p.getTipo().toString() + ".png"));					
		}
		 for(Marker marker : getMapaModel().getMarkers()) {  
	            marker.setDraggable(true);  
	        }  	
	}
	
	 public void onMarkerDrag(MarkerDragEvent event) { 	 
		  	marker = (Marker) event.getMarker();
	        for (PuntoInteres pi : getEntity().getPuntosInteres()) {
	        	if (pi.getId().toString().equals(marker.getData()))
	        	{
	        		pi.setCoordenada(new Coordenada(marker.getLatlng().getLat(), marker.getLatlng().getLng()));
	        	}
			}
	          
	    }  
	

}
